<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/multipage/structured-data.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:35:32 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/standard.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/spec.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=../styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  
  <script defer="" crossorigin="" src=../html-dfn.js></script>
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   <hgroup><h1 class=allcaps>HTML</h1><p id=living-standard>Living Standard — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   
   

   
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=common-dom-interfaces.html>← 2.6 Common DOM interfaces</a> — <a href=index.html>Table of Contents</a> — <a href=dom.html>3 Semantics, structure, and APIs of HTML documents →</a></nav><ol class=toc><li id=toc-infrastructure><ol><li><a href=structured-data.html#safe-passing-of-structured-data><span class=secno>2.7</span> Safe passing of structured data</a><ol><li><a href=structured-data.html#serializable-objects><span class=secno>2.7.1</span> Serializable objects</a><li><a href=structured-data.html#transferable-objects><span class=secno>2.7.2</span> Transferable objects</a><li><a href=structured-data.html#structuredserializeinternal><span class=secno>2.7.3</span> StructuredSerializeInternal ( <var>value</var>, <var>forStorage</var> [ ,
  <var>memory</var> ] )</a><li><a href=structured-data.html#structuredserialize><span class=secno>2.7.4</span> StructuredSerialize ( <var>value</var> )</a><li><a href=structured-data.html#structuredserializeforstorage><span class=secno>2.7.5</span> StructuredSerializeForStorage ( <var>value</var> )</a><li><a href=structured-data.html#structureddeserialize><span class=secno>2.7.6</span> StructuredDeserialize ( <var>serialized</var>, <var>targetRealm</var> [ ,
  <var>memory</var> ] )</a><li><a href=structured-data.html#structuredserializewithtransfer><span class=secno>2.7.7</span> StructuredSerializeWithTransfer ( <var>value</var>, <var>transferList</var>
  )</a><li><a href=structured-data.html#structureddeserializewithtransfer><span class=secno>2.7.8</span> StructuredDeserializeWithTransfer ( <var>serializeWithTransferResult</var>,
  <var>targetRealm</var> )</a><li><a href=structured-data.html#performing-structured-clones-from-other-specifications><span class=secno>2.7.9</span> Performing serialization and
  transferring from other specifications</a><li><a href=structured-data.html#structured-cloning><span class=secno>2.7.10</span> Structured cloning API</a></ol></ol></ol><h3 id=safe-passing-of-structured-data><span class=secno>2.7</span> Safe passing of structured data<a href=#safe-passing-of-structured-data class=self-link></a></h3>

  <p id=structuredclone><span id=structured-clone></span>To support passing JavaScript objects,
  including <a href=https://webidl.spec.whatwg.org/#dfn-platform-object id=safe-passing-of-structured-data:platform-object data-x-internal=platform-object>platform objects</a>, across <a id=safe-passing-of-structured-data:realm href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>
  boundaries, this specification defines the following infrastructure for
  serializing and deserializing objects, including in some cases transferring the underlying data
  instead of copying it. Collectively this serialization/deserialization process is known as
  "structured cloning", although most APIs perform separate serialization and deserialization steps.
  (With the notable exception being the <code id=safe-passing-of-structured-data:dom-structuredclone><a href=#dom-structuredclone>structuredClone()</a></code>
  method.)</p>

  

  <p>This section uses the terminology and typographic conventions from the JavaScript
  specification. <a href=references.html#refsJAVASCRIPT>[JAVASCRIPT]</a></p>

  

  <h4 id=serializable-objects data-lt="serializable object" data-export=""><span class=secno>2.7.1</span> <dfn>Serializable objects</dfn><a href=#serializable-objects class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/https://developer.mozilla.org/en-US/docs/Glossary/Serializable_object title="Serializable objects are objects that can be serialized and later deserialized in any JavaScript environment (&quot;realm&quot;). This allows them to, for example, be stored on disk and later restored, or cloned with structuredClone(), or shared between workers using DedicatedWorkerGlobalScope.postMessage().">/developer.mozilla.org/en-US/docs/Glossary/Serializable_object</a><div class=support><span class="firefox yes"><span>Firefox</span><span>103+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <p><a href=#serializable-objects id=serializable-objects:serializable-objects>Serializable objects</a> support being serialized, and later deserialized, in a way
  that is independent of any given <a id=serializable-objects:realm href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>. This allows them to be stored on disk and
  later restored, or cloned across <a id=serializable-objects:agent href=https://tc39.es/ecma262/#sec-agents data-x-internal=agent>agent</a> and even <a id=serializable-objects:agent-cluster href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a>
  boundaries.</p>

  <p>Not all objects are <a href=#serializable-objects id=serializable-objects:serializable-objects-2>serializable objects</a>, and not all aspects of objects that are
  <a href=#serializable-objects id=serializable-objects:serializable-objects-3>serializable objects</a> are necessarily preserved when they are serialized.</p>

  

  <p><a href=https://webidl.spec.whatwg.org/#dfn-platform-object id=serializable-objects:platform-object data-x-internal=platform-object>Platform objects</a> can be <a href=#serializable-objects id=serializable-objects:serializable-objects-4>serializable objects</a>
  if their <a id=serializable-objects:primary-interface href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a> is decorated with the <dfn id=serializable data-dfn-type=extended-attribute data-lt=Serializable><code>[Serializable]</code></dfn> IDL <a id=serializable-objects:extended-attribute href=https://webidl.spec.whatwg.org/#dfn-extended-attribute data-x-internal=extended-attribute>extended
  attribute</a>. Such interfaces must also define the following algorithms:</p>

  <dl><dt><dfn id=serialization-steps data-export="">serialization steps</dfn>, taking a <a id=serializable-objects:platform-object-2 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>
   <var>value</var>, a <a id=serializable-objects:record href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> <var>serialized</var>, and a boolean
   <var>forStorage</var><dd>
    <p>A set of steps that serializes the data in <var>value</var> into fields of
    <var>serialized</var>. The resulting data serialized into <var>serialized</var> must be
    independent of any <a id=serializable-objects:realm-2 href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>.</p>

    <p>These steps may throw an exception if serialization is not possible.</p>

    <p>These steps may perform a <a href=#sub-serialization id=serializable-objects:sub-serialization>sub-serialization</a> to serialize nested data
    structures. They should not call <a href=#structuredserialize id=serializable-objects:structuredserialize>StructuredSerialize</a> directly, as doing so will
    omit the important <var>memory</var> argument.</p>

    <p>The introduction of these steps should omit mention of the <var>forStorage</var> argument if
    it is not relevant to the algorithm.</p>
   <dt><dfn id=deserialization-steps data-export="">deserialization steps</dfn>, taking a <a id=serializable-objects:record-2 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> <var>serialized</var>,
   a <a id=serializable-objects:platform-object-3 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> <var>value</var>, and a <a id=serializable-objects:realm-3 href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>
   <var>targetRealm</var><dd>
    <p>A set of steps that deserializes the data in <var>serialized</var>, using it to set up
    <var>value</var> as appropriate. <var>value</var> will be a newly-created instance of the
    <a id=serializable-objects:platform-object-4 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> type in question, with none of its internal data set up; setting
    that up is the job of these steps.</p>

    <p>These steps may throw an exception if deserialization is not possible.</p>

    <p>These steps may perform a <a href=#sub-deserialization id=serializable-objects:sub-deserialization>sub-deserialization</a> to deserialize nested data
    structures. They should not call <a href=#structureddeserialize id=serializable-objects:structureddeserialize>StructuredDeserialize</a> directly, as doing so will
    omit the important <var>targetRealm</var> and <var>memory</var> arguments.</p>
   </dl>

  <p>It is up to the definition of individual platform objects to determine what data is serialized
  and deserialized by these steps. Typically the steps are very symmetric.</p>

  <p>The <code id=serializable-objects:serializable><a href=#serializable>[Serializable]</a></code> extended attribute must take no
  arguments, and must only appear on an interface. It must not appear more than once on an
  interface.</p>

  <p>For a given <a id=serializable-objects:platform-object-5 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>, only the object's <a id=serializable-objects:primary-interface-2 href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a> is
  considered during the (de)serialization process. Thus, if inheritance is involved in defining the
  interface, each <code id=serializable-objects:serializable-2><a href=#serializable>[Serializable]</a></code>-annotated interface in the
  inheritance chain needs to define standalone <a href=#serialization-steps id=serializable-objects:serialization-steps>serialization steps</a> and
  <a href=#deserialization-steps id=serializable-objects:deserialization-steps>deserialization steps</a>, including taking into account any important data that might
  come from inherited interfaces.</p>

  <div class=example>
   <p>Let's say we were defining a platform object <code>Person</code>, which had
   associated with it two pieces of associated data:</p>

   <ul><li><p>a name value, which is a string; and<li><p>a best friend value, which is either another <code>Person</code> instance
    or null.</ul>

   <p>We could then define <code>Person</code> instances to be <a href=#serializable-objects id=serializable-objects:serializable-objects-5>serializable
   objects</a> by annotating the <code>Person</code> interface with the <code id=serializable-objects:serializable-3><a href=#serializable>[Serializable]</a></code> <a id=serializable-objects:extended-attribute-2 href=https://webidl.spec.whatwg.org/#dfn-extended-attribute data-x-internal=extended-attribute>extended attribute</a>, and defining the
   following accompanying algorithms:</p>

   <p>Their <a href=#serialization-steps id=serializable-objects:serialization-steps-2>serialization steps</a>, given <var>value</var> and <var>serialized</var>:</p>

   <ol><li><p>Set <var>serialized</var>.[[Name]] to <var>value</var>'s associated name
    value.<li><p>Let <var>serializedBestFriend</var> be the <a href=#sub-serialization id=serializable-objects:sub-serialization-2>sub-serialization</a> of
    <var>value</var>'s associated best friend value.<li><p>Set <var>serialized</var>.[[BestFriend]] to <var>serializedBestFriend</var>.</ol>

   <p>Their <a href=#deserialization-steps id=serializable-objects:deserialization-steps-2>deserialization steps</a>, given <var>serialized</var>, <var>value</var>, and
   <var>targetRealm</var>:</p>

   <ol><li><p>Set <var>value</var>'s associated name value to
    <var>serialized</var>.[[Name]].<li><p>Let <var>deserializedBestFriend</var> be the <a href=#sub-deserialization id=serializable-objects:sub-deserialization-2>sub-deserialization</a> of
    <var>serialized</var>.[[BestFriend]].<li><p>Set <var>value</var>'s associated best friend value to
    <var>deserializedBestFriend</var>.</ol>
  </div>

  <p>Objects defined in the JavaScript specification are handled by the
  <a href=#structuredserialize id=serializable-objects:structuredserialize-2>StructuredSerialize</a> abstract operation directly.</p>

  <p id=cloneable-objects class=note><a href=#cloneable-objects class=self-link></a>Originally, this specification defined the concept of
  "cloneable objects", which could be cloned from one <a id=serializable-objects:realm-4 href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a> to another. However, to
  better specify the behavior of certain more complex situations, the model was updated to make the
  serialization and deserialization explicit.</p>

  

  <h4 id=transferable-objects data-lt="transferable object" data-export=""><span class=secno>2.7.2</span> <dfn>Transferable objects</dfn><a href=#transferable-objects class=self-link></a></h4>

  <p><a href=#transferable-objects id=transferable-objects:transferable-objects>Transferable objects</a> support being transferred across <a href=https://tc39.es/ecma262/#sec-agents id=transferable-objects:agent data-x-internal=agent>agents</a>. Transferring is effectively recreating the object while sharing a
  reference to the underlying data and then detaching the object being transferred. This is useful
  to transfer ownership of expensive resources. Not all objects are <a href=#transferable-objects id=transferable-objects:transferable-objects-2>transferable
  objects</a> and not all aspects of objects that are <a href=#transferable-objects id=transferable-objects:transferable-objects-3>transferable objects</a> are
  necessarily preserved when transferred.</p>

  <p class=note>Transferring is an irreversible and non-idempotent operation. Once an object has
  been transferred, it cannot be transferred, or indeed used, again.</p>

  

  <p><a href=https://webidl.spec.whatwg.org/#dfn-platform-object id=transferable-objects:platform-object data-x-internal=platform-object>Platform objects</a> can be <a href=#transferable-objects id=transferable-objects:transferable-objects-4>transferable objects</a>
  if their <a id=transferable-objects:primary-interface href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a> is decorated with the <dfn id=transferable data-dfn-type=extended-attribute data-lt=Transferable><code>[Transferable]</code></dfn> IDL <a id=transferable-objects:extended-attribute href=https://webidl.spec.whatwg.org/#dfn-extended-attribute data-x-internal=extended-attribute>extended
  attribute</a>. Such interfaces must also define the following algorithms:</p>

  <dl><dt><dfn id=transfer-steps data-export="">transfer steps</dfn>, taking a <a id=transferable-objects:platform-object-2 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>
   <var>value</var> and a <a id=transferable-objects:record href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> <var>dataHolder</var><dd>
    <p>A set of steps that transfers the data in <var>value</var> into fields of
    <var>dataHolder</var>. The resulting data held in <var>dataHolder</var> must be
    independent of any <a id=transferable-objects:realm href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>.</p>

    <p>These steps may throw an exception if transferral is not possible.</p>
   <dt><dfn id=transfer-receiving-steps data-export="">transfer-receiving steps</dfn>, taking a <a id=transferable-objects:record-2 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a>
   <var>dataHolder</var> and a <a id=transferable-objects:platform-object-3 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> <var>value</var><dd>
    <p>A set of steps that receives the data in <var>dataHolder</var>, using it to set up
    <var>value</var> as appropriate. <var>value</var> will be a newly-created instance of the
    <a id=transferable-objects:platform-object-4 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> type in question, with none of its internal data set up; setting
    that up is the job of these steps.</p>

    <p>These steps may throw an exception if it is not possible to receive the transfer.</p>
   </dl>

  <p>It is up to the definition of individual platform objects to determine what data is transferred
  by these steps. Typically the steps are very symmetric.</p>

  <p>The <code id=transferable-objects:transferable><a href=#transferable>[Transferable]</a></code> extended attribute must take no
  arguments, and must only appear on an interface. It must not appear more than once on an
  interface.</p>

  <p>For a given <a id=transferable-objects:platform-object-5 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>, only the object's <a id=transferable-objects:primary-interface-2 href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a> is
  considered during the transferring process. Thus, if inheritance is involved in defining the
  interface, each <code id=transferable-objects:transferable-2><a href=#transferable>[Transferable]</a></code>-annotated interface in the
  inheritance chain needs to define standalone <a href=#transfer-steps id=transferable-objects:transfer-steps>transfer steps</a> and
  <a href=#transfer-receiving-steps id=transferable-objects:transfer-receiving-steps>transfer-receiving steps</a>, including taking into account any important data that might
  come from inherited interfaces.</p>

  <p><a href=https://webidl.spec.whatwg.org/#dfn-platform-object id=transferable-objects:platform-object-6 data-x-internal=platform-object>Platform objects</a> that are <a href=#transferable-objects id=transferable-objects:transferable-objects-5>transferable
  objects</a> have a <dfn data-dfn-for="platform object" id=detached data-dfn-type=attribute>[[Detached]]</dfn> internal slot. This
  is used to ensure that once a platform object has been transferred, it cannot be transferred
  again.</p>

  <p>Objects defined in the JavaScript specification are handled by the
  <a href=#structuredserializewithtransfer id=transferable-objects:structuredserializewithtransfer>StructuredSerializeWithTransfer</a> abstract operation directly.</p>

  <h4 id=structuredserializeinternal data-dfn-type=abstract-op data-noexport="" data-lt=StructuredSerializeInternal><span class=secno>2.7.3</span> <dfn>StructuredSerializeInternal</dfn> ( <var>value</var>, <var>forStorage</var> [ ,
  <var>memory</var> ] )<a href=#structuredserializeinternal class=self-link></a></h4>

  <p>The <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal>StructuredSerializeInternal</a> abstract operation takes as input a JavaScript
  value <var>value</var> and serializes it to a <a id=structuredserializeinternal:realm href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>-independent form, represented
  here as a <a id=structuredserializeinternal:record href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a>. This serialized form has all the information necessary to later
  deserialize into a new JavaScript value in a different realm.</p>

  <p>This process can throw an exception, for example when trying to serialize un-serializable
  objects.</p>

  <ol><li>
    <p>If <var>memory</var> was not supplied, let <var>memory</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-map id=structuredserializeinternal:ordered-map data-x-internal=ordered-map>map</a>.</p>

    <p class=note>The purpose of the <var>memory</var> map is to avoid serializing objects twice.
    This ends up preserving cycles and the identity of duplicate objects in graphs.</p>
   <li><p>If <var>memory</var>[<var>value</var>] <a href=https://infra.spec.whatwg.org/#map-exists id=structuredserializeinternal:map-exists data-x-internal=map-exists>exists</a>, then
   return <var>memory</var>[<var>value</var>].<li><p>Let <var>deep</var> be false.<li><p>If <var>value</var> is undefined, null, <a href=https://tc39.es/ecma262/#sec-ecmascript-language-types-boolean-type id=structuredserializeinternal:js-boolean data-x-internal=js-boolean>a Boolean</a>, <a href=https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type id=structuredserializeinternal:js-number data-x-internal=js-number>a Number</a>, <a href=https://tc39.es/ecma262/#sec-ecmascript-language-types-bigint-type id=structuredserializeinternal:js-bigint data-x-internal=js-bigint>a BigInt</a>, or <a href=https://tc39.es/ecma262/#sec-ecmascript-language-types-string-type id=structuredserializeinternal:js-string data-x-internal=js-string>a String</a>, then return { [[Type]]: "primitive", [[Value]]:
   <var>value</var> }.<li><p>If <var>value</var> <a href=https://tc39.es/ecma262/#sec-ecmascript-language-types-symbol-type id=structuredserializeinternal:js-symbol data-x-internal=js-symbol>is a Symbol</a>, then throw a
   <a id=structuredserializeinternal:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>serialized</var> be an uninitialized value.<li><p>If <var>value</var> has a [[BooleanData]] internal slot, then set <var>serialized</var> to
   { [[Type]]: "Boolean", [[BooleanData]]: <var>value</var>.[[BooleanData]] }.<li><p>Otherwise, if <var>value</var> has a [[NumberData]] internal slot, then set
   <var>serialized</var> to { [[Type]]: "Number", [[NumberData]]: <var>value</var>.[[NumberData]]
   }.<li><p>Otherwise, if <var>value</var> has a [[BigIntData]]
   internal slot, then set <var>serialized</var> to { [[Type]]: "BigInt", [[BigIntData]]:
   <var>value</var>.[[BigIntData]] }.<li><p>Otherwise, if <var>value</var> has a [[StringData]] internal slot, then set
   <var>serialized</var> to { [[Type]]: "String", [[StringData]]: <var>value</var>.[[StringData]]
   }.<li><p>Otherwise, if <var>value</var> has a [[DateValue]] internal slot, then set
   <var>serialized</var> to { [[Type]]: "Date", [[DateValue]]: <var>value</var>.[[DateValue]]
   }.<li><p>Otherwise, if <var>value</var> has a [[RegExpMatcher]] internal slot, then set
   <var>serialized</var> to { [[Type]]: "RegExp", [[RegExpMatcher]]:
   <var>value</var>.[[RegExpMatcher]], [[OriginalSource]]: <var>value</var>.[[OriginalSource]],
   [[OriginalFlags]]: <var>value</var>.[[OriginalFlags]] }.<li>
    <p>Otherwise, if <var>value</var> has an [[ArrayBufferData]] internal slot, then:</p>

    <ol><li>
      <p>If <a id=structuredserializeinternal:issharedarraybuffer href=https://tc39.es/ecma262/#sec-issharedarraybuffer data-x-internal=issharedarraybuffer>IsSharedArrayBuffer</a>(<var>value</var>) is true, then:

      <ol><li>
        <p>If the <a id=structuredserializeinternal:current-settings-object href=webappapis.html#current-settings-object>current settings object</a>'s <a href=webappapis.html#concept-settings-object-cross-origin-isolated-capability id=structuredserializeinternal:concept-settings-object-cross-origin-isolated-capability>cross-origin isolated
        capability</a> is false, then throw a <a id=structuredserializeinternal:datacloneerror-2 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a>
        <code id=structuredserializeinternal:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

        <p class=note>This check is only needed when serializing (and not when deserializing) as
        the <a href=webappapis.html#concept-settings-object-cross-origin-isolated-capability id=structuredserializeinternal:concept-settings-object-cross-origin-isolated-capability-2>cross-origin
        isolated capability</a> cannot change over time and a <code id=structuredserializeinternal:sharedarraybuffer><a data-x-internal=sharedarraybuffer href=https://tc39.es/ecma262/#sec-sharedarraybuffer-objects>SharedArrayBuffer</a></code>
        cannot leave an <a id=structuredserializeinternal:agent-cluster href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a>.</p>
       <li><p>If <var>forStorage</var> is true, then throw a
       <a id=structuredserializeinternal:datacloneerror-3 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>value</var> has an [[ArrayBufferMaxByteLength]] internal slot, then set
       <var>serialized</var> to { [[Type]]: "GrowableSharedArrayBuffer", [[ArrayBufferData]]:
       <var>value</var>.[[ArrayBufferData]], [[ArrayBufferByteLengthData]]:
       <var>value</var>.[[ArrayBufferByteLengthData]], [[ArrayBufferMaxByteLength]]:
       <var>value</var>.[[ArrayBufferMaxByteLength]], [[AgentCluster]]: the <a id=structuredserializeinternal:surrounding-agent href=https://tc39.es/ecma262/#surrounding-agent data-x-internal=surrounding-agent>surrounding
       agent</a>'s <a id=structuredserializeinternal:agent-cluster-2 href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a> }.<li><p>Otherwise, set <var>serialized</var> to { [[Type]]: "SharedArrayBuffer",
       [[ArrayBufferData]]: <var>value</var>.[[ArrayBufferData]], [[ArrayBufferByteLength]]:
       <var>value</var>.[[ArrayBufferByteLength]], [[AgentCluster]]: the <a id=structuredserializeinternal:surrounding-agent-2 href=https://tc39.es/ecma262/#surrounding-agent data-x-internal=surrounding-agent>surrounding
       agent</a>'s <a id=structuredserializeinternal:agent-cluster-3 href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a> }.</ol>
     <li>
      <p>Otherwise:</p>

      <ol><li><p>If <a id=structuredserializeinternal:isdetachedbuffer href=https://tc39.es/ecma262/#sec-isdetachedbuffer data-x-internal=isdetachedbuffer>IsDetachedBuffer</a>(<var>value</var>) is true, then throw a
       <a id=structuredserializeinternal:datacloneerror-4 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>size</var> be <var>value</var>.[[ArrayBufferByteLength]].<li>
        <p>Let <var>dataCopy</var> be ? <a id=structuredserializeinternal:createbytedatablock href=https://tc39.es/ecma262/#sec-createbytedatablock data-x-internal=createbytedatablock>CreateByteDataBlock</a>(<var>size</var>).</p>

        <p class=note>This can throw a <code id=structuredserializeinternal:js-rangeerror><a data-x-internal=js-rangeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror>RangeError</a></code> exception
        upon allocation failure.</p>
       <li><p>Perform <a id=structuredserializeinternal:copydatablockbytes href=https://tc39.es/ecma262/#sec-copydatablockbytes data-x-internal=copydatablockbytes>CopyDataBlockBytes</a>(<var>dataCopy</var>, 0,
       <var>value</var>.[[ArrayBufferData]], 0, <var>size</var>).<li><p>If <var>value</var> has an [[ArrayBufferMaxByteLength]] internal slot, then set
       <var>serialized</var> to { [[Type]]: "ResizableArrayBuffer", [[ArrayBufferData]]:
       <var>dataCopy</var>, [[ArrayBufferByteLength]]: <var>size</var>,
       [[ArrayBufferMaxByteLength]]: <var>value</var>.[[ArrayBufferMaxByteLength]] }.<li><p>Otherwise, set <var>serialized</var> to { [[Type]]: "ArrayBuffer",
       [[ArrayBufferData]]: <var>dataCopy</var>, [[ArrayBufferByteLength]]: <var>size</var>
       }.</ol>
     </ol>
   <li>
    <p>Otherwise, if <var>value</var> has a [[ViewedArrayBuffer]] internal slot, then:</p>

    <ol><li><p>If <a id=structuredserializeinternal:isarraybufferviewoutofbounds href=https://tc39.es/ecma262/#sec-isarraybufferviewoutofbounds data-x-internal=isarraybufferviewoutofbounds>IsArrayBufferViewOutOfBounds</a>(<var>value</var>) is true, then throw a
     <a id=structuredserializeinternal:datacloneerror-5 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-5><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>buffer</var> be the value of <var>value</var>'s [[ViewedArrayBuffer]] internal
     slot.<li><p>Let <var>bufferSerialized</var> be ?
     <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-2>StructuredSerializeInternal</a>(<var>buffer</var>, <var>forStorage</var>,
     <var>memory</var>).<li><p><a id=structuredserializeinternal:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>bufferSerialized</var>.[[Type]] is "ArrayBuffer",
     "ResizableArrayBuffer", "SharedArrayBuffer", or "GrowableSharedArrayBuffer".<li><p>If <var>value</var> has a [[DataView]] internal slot, then set <var>serialized</var> to
     { [[Type]]: "ArrayBufferView", [[Constructor]]: "DataView", [[ArrayBufferSerialized]]:
     <var>bufferSerialized</var>, [[ByteLength]]: <var>value</var>.[[ByteLength]], [[ByteOffset]]:
     <var>value</var>.[[ByteOffset]] }.<li>
      <p>Otherwise:</p>

      <ol><li><p><a id=structuredserializeinternal:assert-2 href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>value</var> has a [[TypedArrayName]] internal slot.<li><p>Set <var>serialized</var> to { [[Type]]: "ArrayBufferView", [[Constructor]]:
       <var>value</var>.[[TypedArrayName]], [[ArrayBufferSerialized]]: <var>bufferSerialized</var>,
       [[ByteLength]]: <var>value</var>.[[ByteLength]], [[ByteOffset]]:
       <var>value</var>.[[ByteOffset]], [[ArrayLength]]: <var>value</var>.[[ArrayLength]] }.</ol>
     </ol>
   <li>
    <p>Otherwise, if <var>value</var> has a [[MapData]] internal slot, then:</p>

    <ol><li><p>Set <var>serialized</var> to { [[Type]]: "Map", [[MapData]]: a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list data-x-internal=js-list>List</a> }.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>value</var> has a [[SetData]] internal slot, then:</p>

    <ol><li><p>Set <var>serialized</var> to { [[Type]]: "Set", [[SetData]]: a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list-2 data-x-internal=js-list>List</a> }.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>value</var> has an [[ErrorData]] internal slot and <var>value</var> is not
    a <a id=structuredserializeinternal:platform-object href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>, then:</p>
    

    <ol><li><p>Let <var>name</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=structuredserializeinternal:js-get data-x-internal=js-get>Get</a>(<var>value</var>,
     "name").<li><p>If <var>name</var> is not one of "Error", "EvalError", "RangeError", "ReferenceError",
     "SyntaxError", "TypeError", or "URIError", then set <var>name</var> to "Error".<li><p>Let <var>valueMessageDesc</var> be ? <var>value</var>.[[GetOwnProperty]]("<code>message</code>").<li><p>Let <var>message</var> be undefined if
     <a id=structuredserializeinternal:isdatadescriptor href=https://tc39.es/ecma262/#sec-isdatadescriptor data-x-internal=isdatadescriptor>IsDataDescriptor</a>(<var>valueMessageDesc</var>) is false, and
     ? <a id=structuredserializeinternal:tostring href=https://tc39.es/ecma262/#sec-tostring data-x-internal=tostring>ToString</a>(<var>valueMessageDesc</var>.[[Value]]) otherwise.<li><p>Set <var>serialized</var> to { [[Type]]: "Error", [[Name]]: <var>name</var>,
     [[Message]]: <var>message</var> }.<li>
      <p>User agents should attach a serialized representation of any interesting accompanying
      data which are not yet specified, notably the <code>stack</code> property, to
      <var>serialized</var>.</p>

      <p class=note>See the <cite>Error Stacks</cite> proposal for in-progress work on specifying
      this data. <a href=references.html#refsJSERRORSTACKS>[JSERRORSTACKS]</a></p>
     </ol>
   <li>
    <p>Otherwise, if <var>value</var> is an Array exotic object, then:</p>
    

    <ol><li><p>Let <var>valueLenDescriptor</var> be ?
     <a id=structuredserializeinternal:ordinarygetownproperty href=https://tc39.es/ecma262/#sec-ordinarygetownproperty data-x-internal=ordinarygetownproperty>OrdinaryGetOwnProperty</a>(<var>value</var>, "<code>length</code>").<li><p>Let <var>valueLen</var> be <var>valueLenDescriptor</var>.[[Value]].<li><p>Set <var>serialized</var> to { [[Type]]: "Array", [[Length]]: <var>valueLen</var>,
     [[Properties]]: a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list-3 data-x-internal=js-list>List</a> }.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>value</var> is a <a id=structuredserializeinternal:platform-object-2 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> that is a <a href=#serializable-objects id=structuredserializeinternal:serializable-objects>serializable object</a>:</p>

    <ol><li><p>If <var>value</var> has a <a href=#detached id=structuredserializeinternal:detached>[[Detached]]</a> internal slot whose value is true,
     then throw a <a id=structuredserializeinternal:datacloneerror-6 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-6><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>typeString</var> be the identifier of the <a id=structuredserializeinternal:primary-interface href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a> of
     <var>value</var>.<li><p>Set <var>serialized</var> to { [[Type]]: <var>typeString</var> }.<li><p>Set <var>deep</var> to true.</ol>
   <li><p>Otherwise, if <var>value</var> is a <a id=structuredserializeinternal:platform-object-3 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a>, then throw a
   <a id=structuredserializeinternal:datacloneerror-7 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-7><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Otherwise, if <a id=structuredserializeinternal:iscallable href=https://tc39.es/ecma262/#sec-iscallable data-x-internal=iscallable>IsCallable</a>(<var>value</var>) is true, then throw a
   <a id=structuredserializeinternal:datacloneerror-8 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-8><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li>
    <p>Otherwise, if <var>value</var> has any internal slot other than [[Prototype]],
    [[Extensible]], or [[PrivateElements]], then throw a <a id=structuredserializeinternal:datacloneerror-9 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a>
    <code id=structuredserializeinternal:domexception-9><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

    <p class=example>For instance, a [[PromiseState]] or [[WeakMapData]] internal slot.</p>
   <li>
    <p>Otherwise, if <var>value</var> is an exotic object and <var>value</var> is not the
    <a id=structuredserializeinternal:object.prototype href=https://tc39.es/ecma262/#sec-properties-of-the-object-prototype-object data-x-internal=object.prototype>%Object.prototype%</a> intrinsic object associated with any <a id=structuredserializeinternal:realm-2 href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>, then
    throw a <a id=structuredserializeinternal:datacloneerror-10 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializeinternal:domexception-10><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

    <p class=example>For instance, a proxy object.</p>
   <li>
    <p>Otherwise:</p>

    <ol><li><p>Set <var>serialized</var> to { [[Type]]: "Object", [[Properties]]: a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list-4 data-x-internal=js-list>List</a> }.<li><p>Set <var>deep</var> to true.</ol>

    <p class=note><a id=structuredserializeinternal:object.prototype-2 href=https://tc39.es/ecma262/#sec-properties-of-the-object-prototype-object data-x-internal=object.prototype>%Object.prototype%</a> will end up being handled via this step and
    subsequent steps. The end result is that its exoticness is ignored, and after deserialization
    the result will be an empty object (not an <a id=structuredserializeinternal:immutable-prototype-exotic-object href=https://tc39.es/ecma262/#immutable-prototype-exotic-object data-x-internal=immutable-prototype-exotic-object>immutable prototype exotic object</a>).
   <li><p><a href=https://infra.spec.whatwg.org/#map-set id=structuredserializeinternal:map-set data-x-internal=map-set>Set</a> <var>memory</var>[<var>value</var>] to
   <var>serialized</var>.<li>
    <p>If <var>deep</var> is true, then:</p>

    <ol><li>
      <p>If <var>value</var> has a [[MapData]] internal slot, then:

      <ol><li><p>Let <var>copiedList</var> be a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list-5 data-x-internal=js-list>List</a>.

       <li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializeinternal:list-iterate data-x-internal=list-iterate>For each</a> <a id=structuredserializeinternal:record-2 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> { [[Key]], [[Value]] }
        <var>entry</var> of <var>value</var>.[[MapData]]:</p>

        <ol><li><p>Let <var>copiedEntry</var> be a new <a id=structuredserializeinternal:record-3 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> { [[Key]]:
         <var>entry</var>.[[Key]], [[Value]]: <var>entry</var>.[[Value]] }.<li><p>If <var>copiedEntry</var>.[[Key]] is not the special value <i>empty</i>, <a href=https://infra.spec.whatwg.org/#list-append id=structuredserializeinternal:list-append data-x-internal=list-append>append</a> <var>copiedEntry</var> to <var>copiedList</var>.</ol>
       <li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializeinternal:list-iterate-2 data-x-internal=list-iterate>For each</a> <a id=structuredserializeinternal:record-4 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> { [[Key]], [[Value]] }
        <var>entry</var> of <var>copiedList</var>:</p>

        <ol><li><p>Let <var>serializedKey</var> be ?
         <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-3>StructuredSerializeInternal</a>(<var>entry</var>.[[Key]], <var>forStorage</var>,
         <var>memory</var>).<li><p>Let <var>serializedValue</var> be ?
         <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-4>StructuredSerializeInternal</a>(<var>entry</var>.[[Value]], <var>forStorage</var>,
         <var>memory</var>).<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structuredserializeinternal:list-append-2 data-x-internal=list-append>Append</a> { [[Key]]: <var>serializedKey</var>,
         [[Value]]: <var>serializedValue</var> } to <var>serialized</var>.[[MapData]].</ol>
       </ol>
     <li>
      <p>Otherwise, if <var>value</var> has a [[SetData]] internal slot, then:</p>

      <ol><li><p>Let <var>copiedList</var> be a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:js-list-6 data-x-internal=js-list>List</a>.

       <li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializeinternal:list-iterate-3 data-x-internal=list-iterate>For each</a> <var>entry</var> of <var>value</var>.[[SetData]]:</p>

        <ol><li><p>If <var>entry</var> is not the special value <i>empty</i>, <a href=https://infra.spec.whatwg.org/#list-append id=structuredserializeinternal:list-append-3 data-x-internal=list-append>append</a> <var>entry</var> to <var>copiedList</var>.</ol>
       <li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializeinternal:list-iterate-4 data-x-internal=list-iterate>For each</a> <var>entry</var> of <var>copiedList</var>:</p>

        <ol><li><p>Let <var>serializedEntry</var> be ?
         <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-5>StructuredSerializeInternal</a>(<var>entry</var>, <var>forStorage</var>,
         <var>memory</var>).<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structuredserializeinternal:list-append-4 data-x-internal=list-append>Append</a> <var>serializedEntry</var> to
         <var>serialized</var>.[[SetData]].</ol>
       </ol>
     <li>
      <p>Otherwise, if <var>value</var> is a <a id=structuredserializeinternal:platform-object-4 href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> that is a <a href=#serializable-objects id=structuredserializeinternal:serializable-objects-2>serializable object</a>, then perform the <a href=#serialization-steps id=structuredserializeinternal:serialization-steps>serialization
      steps</a> for <var>value</var>'s <a id=structuredserializeinternal:primary-interface-2 href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a>, given <var>value</var>,
      <var>serialized</var>, and <var>forStorage</var>.</p>

      <p>The <a href=#serialization-steps id=structuredserializeinternal:serialization-steps-2>serialization steps</a> may need to perform a <dfn id=sub-serialization data-export="">sub-serialization</dfn>. This is an operation which takes as input a value
      <var>subValue</var>, and returns <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-6>StructuredSerializeInternal</a>(<var>subValue</var>,
      <var>forStorage</var>, <var>memory</var>). (In other words, a <a href=#sub-serialization id=structuredserializeinternal:sub-serialization>sub-serialization</a>
      is a specialization of <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-7>StructuredSerializeInternal</a> to be consistent within this
      invocation.)</p>
     <li>
      <p>Otherwise, for each <var>key</var> in !
      <a id=structuredserializeinternal:enumerableownproperties href=https://tc39.es/ecma262/#sec-enumerableownproperties data-x-internal=enumerableownproperties>EnumerableOwnProperties</a>(<var>value</var>, key):</p>

      <ol><li>
        <p>If ! <a id=structuredserializeinternal:hasownproperty href=https://tc39.es/ecma262/#sec-hasownproperty data-x-internal=hasownproperty>HasOwnProperty</a>(<var>value</var>, <var>key</var>) is true, then:</p>

        <ol><li><p>Let <var>inputValue</var> be ? <var>value</var>.[[Get]](<var>key</var>,
         <var>value</var>).<li><p>Let <var>outputValue</var> be ?
         <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-8>StructuredSerializeInternal</a>(<var>inputValue</var>, <var>forStorage</var>,
         <var>memory</var>).<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structuredserializeinternal:list-append-5 data-x-internal=list-append>Append</a> { [[Key]]: <var>key</var>, [[Value]]:
         <var>outputValue</var> } to <var>serialized</var>.[[Properties]].</ol>
       </ol>
     </ol>
   <li><p>Return <var>serialized</var>.</ol>

  <div class=example>
   <p>It's important to realize that the <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializeinternal:record-5 data-x-internal=record>Records</a>
   produced by <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-9>StructuredSerializeInternal</a> might contain "pointers" to other records
   that create circular references. For example, when we pass the following JavaScript object into
   <a href=#structuredserializeinternal id=structuredserializeinternal:structuredserializeinternal-10>StructuredSerializeInternal</a>:</p>

  <pre><code class='js'><c- a>const</c-> o <c- o>=</c-> <c- p>{};</c->
o<c- p>.</c->myself <c- o>=</c-> o<c- p>;</c-></code></pre>

  <p>it produces the following result:</p>

  <pre><samp>{
  [[Type]]: "Object",
  [[Properties]]: «
    {
      [[Key]]: "myself",
      [[Value]]: <i>&lt;a pointer to this whole structure></i>
    }
  »
}</samp></pre>
  </div>


  <h4 id=structuredserialize data-dfn-type=abstract-op data-lt=StructuredSerialize><span class=secno>2.7.4</span> <dfn>StructuredSerialize</dfn> ( <var>value</var> )<a href=#structuredserialize class=self-link></a></h4>

  <ol><li><p>Return ? <a href=#structuredserializeinternal id=structuredserialize:structuredserializeinternal>StructuredSerializeInternal</a>(<var>value</var>, false).</ol>


  <h4 id=structuredserializeforstorage data-dfn-type=abstract-op data-lt=StructuredSerializeForStorage><span class=secno>2.7.5</span> <dfn>StructuredSerializeForStorage</dfn> ( <var>value</var> )<a href=#structuredserializeforstorage class=self-link></a></h4>

  <ol><li><p>Return ? <a href=#structuredserializeinternal id=structuredserializeforstorage:structuredserializeinternal>StructuredSerializeInternal</a>(<var>value</var>, true).</ol>


  <h4 id=structureddeserialize data-dfn-type=abstract-op data-lt=StructuredDeserialize><span class=secno>2.7.6</span> <dfn>StructuredDeserialize</dfn> ( <var>serialized</var>, <var>targetRealm</var> [ ,
  <var>memory</var> ] )<a href=#structureddeserialize class=self-link></a></h4>

  <p>The <a href=#structureddeserialize id=structureddeserialize:structureddeserialize>StructuredDeserialize</a> abstract operation takes as input a <a id=structureddeserialize:record href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a>
  <var>serialized</var>, which was previously produced by <a href=#structuredserialize id=structureddeserialize:structuredserialize>StructuredSerialize</a> or
  <a href=#structuredserializeforstorage id=structureddeserialize:structuredserializeforstorage>StructuredSerializeForStorage</a>, and deserializes it into a new JavaScript value,
  created in <var>targetRealm</var>.</p>

  <p>This process can throw an exception, for example when trying to allocate memory for the new
  objects (especially <code>ArrayBuffer</code> objects).</p>

  <ol><li>
    <p>If <var>memory</var> was not supplied, let <var>memory</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-map id=structureddeserialize:ordered-map data-x-internal=ordered-map>map</a>.</p>

    <p class=note>The purpose of the <var>memory</var> map is to avoid deserializing objects
    twice. This ends up preserving cycles and the identity of duplicate objects in graphs.</p>
   <li><p>If <var>memory</var>[<var>serialized</var>] <a href=https://infra.spec.whatwg.org/#map-exists id=structureddeserialize:map-exists data-x-internal=map-exists>exists</a>, then
   return <var>memory</var>[<var>serialized</var>].<li><p>Let <var>deep</var> be false.<li><p>Let <var>value</var> be an uninitialized value.<li><p>If <var>serialized</var>.[[Type]] is "primitive", then set <var>value</var> to
   <var>serialized</var>.[[Value]].</p>

   <li><p>Otherwise, if <var>serialized</var>.[[Type]] is "Boolean", then set <var>value</var> to a
   new Boolean object in <var>targetRealm</var> whose [[BooleanData]] internal slot value is
   <var>serialized</var>.[[BooleanData]].<li><p>Otherwise, if <var>serialized</var>.[[Type]] is "Number", then set <var>value</var> to a
   new Number object in <var>targetRealm</var> whose [[NumberData]] internal slot value is
   <var>serialized</var>.[[NumberData]].<li><p>Otherwise, if <var>serialized</var>.[[Type]] is "BigInt", then set <var>value</var> to a
   new BigInt object in <var>targetRealm</var> whose [[BigIntData]] internal slot value is
   <var>serialized</var>.[[BigIntData]].<li><p>Otherwise, if <var>serialized</var>.[[Type]] is "String", then set <var>value</var> to a
   new String object in <var>targetRealm</var> whose [[StringData]] internal slot value is
   <var>serialized</var>.[[StringData]].<li><p>Otherwise, if <var>serialized</var>.[[Type]] is "Date", then set <var>value</var> to a new
   Date object in <var>targetRealm</var> whose [[DateValue]] internal slot value is
   <var>serialized</var>.[[DateValue]].<li><p>Otherwise, if <var>serialized</var>.[[Type]] is "RegExp", then set <var>value</var> to a
   new RegExp object in <var>targetRealm</var> whose [[RegExpMatcher]] internal slot value is
   <var>serialized</var>.[[RegExpMatcher]], whose [[OriginalSource]] internal slot value is
   <var>serialized</var>.[[OriginalSource]], and whose [[OriginalFlags]] internal slot value is
   <var>serialized</var>.[[OriginalFlags]].<li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "SharedArrayBuffer", then:</p>

    <ol><li><p>If <var>targetRealm</var>'s corresponding <a id=structureddeserialize:agent-cluster href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a> is not
     <var>serialized</var>.[[AgentCluster]], then throw a
     <a id=structureddeserialize:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structureddeserialize:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Otherwise, set <var>value</var> to a new SharedArrayBuffer object in
     <var>targetRealm</var> whose [[ArrayBufferData]] internal slot value is
     <var>serialized</var>.[[ArrayBufferData]] and whose [[ArrayBufferByteLength]] internal slot
     value is <var>serialized</var>.[[ArrayBufferByteLength]].</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "GrowableSharedArrayBuffer", then:</p>

    <ol><li><p>If <var>targetRealm</var>'s corresponding <a id=structureddeserialize:agent-cluster-2 href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a> is not
     <var>serialized</var>.[[AgentCluster]], then throw a
     <a id=structureddeserialize:datacloneerror-2 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structureddeserialize:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Otherwise, set <var>value</var> to a new SharedArrayBuffer object in
     <var>targetRealm</var> whose [[ArrayBufferData]] internal slot value is
     <var>serialized</var>.[[ArrayBufferData]], whose [[ArrayBufferByteLengthData]] internal slot
     value is <var>serialized</var>.[[ArrayBufferByteLengthData]], and whose
     [[ArrayBufferMaxByteLength]] internal slot value is
     <var>serialized</var>.[[ArrayBufferMaxByteLength]].</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "ArrayBuffer", then set <var>value</var> to a
    new ArrayBuffer object in <var>targetRealm</var> whose [[ArrayBufferData]] internal slot value
    is <var>serialized</var>.[[ArrayBufferData]], and whose [[ArrayBufferByteLength]] internal slot
    value is <var>serialized</var>.[[ArrayBufferByteLength]].</p>

    <p>If this throws an exception, catch it, and then throw a
    <a id=structureddeserialize:datacloneerror-3 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structureddeserialize:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

    <p class=note>This step might throw an exception if there is not enough memory available to
    create such an ArrayBuffer object.</p>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "ResizableArrayBuffer", then set
    <var>value</var> to a new ArrayBuffer object in <var>targetRealm</var> whose [[ArrayBufferData]]
    internal slot value is <var>serialized</var>.[[ArrayBufferData]], whose
    [[ArrayBufferByteLength]] internal slot value is
    <var>serialized</var>.[[ArrayBufferByteLength]], and whose [[ArrayBufferMaxByteLength]] internal
    slot value is <var>serialized</var>.[[ArrayBufferMaxByteLength]].</p>

    <p>If this throws an exception, catch it, and then throw a
    <a id=structureddeserialize:datacloneerror-4 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structureddeserialize:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

    <p class=note>This step might throw an exception if there is not enough memory available to
    create such an ArrayBuffer object.</p>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "ArrayBufferView", then:</p>

    <ol><li><p>Let <var>deserializedArrayBuffer</var> be ?
     <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-2>StructuredDeserialize</a>(<var>serialized</var>.[[ArrayBufferSerialized]],
     <var>targetRealm</var>, <var>memory</var>).<li><p>If <var>serialized</var>.[[Constructor]] is "DataView", then set <var>value</var> to a
     new DataView object in <var>targetRealm</var> whose [[ViewedArrayBuffer]] internal slot value
     is <var>deserializedArrayBuffer</var>, whose [[ByteLength]] internal slot value is
     <var>serialized</var>.[[ByteLength]], and whose [[ByteOffset]] internal slot value is
     <var>serialized</var>.[[ByteOffset]].<li><p>Otherwise, set <var>value</var> to a new typed array object in <var>targetRealm</var>,
     using the constructor given by <var>serialized</var>.[[Constructor]], whose
     [[ViewedArrayBuffer]] internal slot value is <var>deserializedArrayBuffer</var>, whose
     [[TypedArrayName]] internal slot value is <var>serialized</var>.[[Constructor]], whose
     [[ByteLength]] internal slot value is <var>serialized</var>.[[ByteLength]], whose
     [[ByteOffset]] internal slot value is <var>serialized</var>.[[ByteOffset]], and whose
     [[ArrayLength]] internal slot value is <var>serialized</var>.[[ArrayLength]].</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "Map", then:</p>

    <ol><li><p>Set <var>value</var> to a new Map object in <var>targetRealm</var> whose [[MapData]]
     internal slot value is a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structureddeserialize:js-list data-x-internal=js-list>List</a>.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "Set", then:</p>

    <ol><li><p>Set <var>value</var> to a new Set object in <var>targetRealm</var> whose [[SetData]]
     internal slot value is a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structureddeserialize:js-list-2 data-x-internal=js-list>List</a>.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "Array", then:</p>

    <ol><li><p>Let <var>outputProto</var> be
     <var>targetRealm</var>.[[Intrinsics]].[[<a id=structureddeserialize:array.prototype href=https://tc39.es/ecma262/#sec-properties-of-the-array-prototype-object data-x-internal=array.prototype>%Array.prototype%</a>]].<li><p>Set <var>value</var> to ! <a id=structureddeserialize:arraycreate href=https://tc39.es/ecma262/#sec-arraycreate data-x-internal=arraycreate>ArrayCreate</a>(<var>serialized</var>.[[Length]],
     <var>outputProto</var>).<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "Object", then:</p>

    <ol><li><p>Set <var>value</var> to a new Object in <var>targetRealm</var>.<li><p>Set <var>deep</var> to true.</ol>
   <li>
    <p>Otherwise, if <var>serialized</var>.[[Type]] is "Error", then:</p>

    <ol><li><p>Let <var>prototype</var> be <a id=structureddeserialize:error.prototype href=https://tc39.es/ecma262/#sec-properties-of-the-error-prototype-object data-x-internal=error.prototype>%Error.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "EvalError", then set <var>prototype</var> to
     <a id=structureddeserialize:evalerror.prototype href=infrastructure.html#evalerror.prototype>%EvalError.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "RangeError", then set <var>prototype</var>
     to <a id=structureddeserialize:rangeerror.prototype href=infrastructure.html#rangeerror.prototype>%RangeError.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "ReferenceError", then set
     <var>prototype</var> to <a id=structureddeserialize:referenceerror.prototype href=infrastructure.html#referenceerror.prototype>%ReferenceError.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "SyntaxError", then set <var>prototype</var>
     to <a id=structureddeserialize:syntaxerror.prototype href=infrastructure.html#syntaxerror.prototype>%SyntaxError.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "TypeError", then set <var>prototype</var> to
     <a id=structureddeserialize:typeerror.prototype href=infrastructure.html#typeerror.prototype>%TypeError.prototype%</a>.<li><p>If <var>serialized</var>.[[Name]] is "URIError", then set <var>prototype</var> to
     <a id=structureddeserialize:urierror.prototype href=infrastructure.html#urierror.prototype>%URIError.prototype%</a>.<li><p>Let <var>message</var> be <var>serialized</var>.[[Message]].<li><p>Set <var>value</var> to <a id=structureddeserialize:ordinaryobjectcreate href=https://tc39.es/ecma262/#sec-objectcreate data-x-internal=ordinaryobjectcreate>OrdinaryObjectCreate</a>(<var>prototype</var>, «
     [[ErrorData]] »).<li><p>Let <var>messageDesc</var> be <a id=structureddeserialize:propertydescriptor href=https://tc39.es/ecma262/#sec-property-descriptor-specification-type data-x-internal=propertydescriptor>PropertyDescriptor</a> { [[Value]]:
     <var>message</var>, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true
     }.<li><p>If <var>message</var> is not undefined, then perform !
     <a id=structureddeserialize:ordinarydefineownproperty href=https://tc39.es/ecma262/#sec-ordinarydefineownproperty data-x-internal=ordinarydefineownproperty>OrdinaryDefineOwnProperty</a>(<var>value</var>, "<code>message</code>",
     <var>messageDesc</var>).<li><p>Any interesting accompanying data attached to <var>serialized</var> should be
     deserialized and attached to <var>value</var>.</ol>
   <li>
    <p>Otherwise:</p>

    <ol><li><p>Let <var>interfaceName</var> be <var>serialized</var>.[[Type]].<li><p>If the interface identified by <var>interfaceName</var> is not
     <a href=https://webidl.spec.whatwg.org/#dfn-exposed id=structureddeserialize:idl-exposed data-x-internal=idl-exposed>exposed</a> in <var>targetRealm</var>, then throw a
     <a id=structureddeserialize:datacloneerror-5 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structureddeserialize:domexception-5><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>value</var> to a new instance of the interface identified by
     <var>interfaceName</var>, created in <var>targetRealm</var>.</p>

     <li><p>Set <var>deep</var> to true.</ol>
   <li><p><a href=https://infra.spec.whatwg.org/#map-set id=structureddeserialize:map-set data-x-internal=map-set>Set</a> <var>memory</var>[<var>serialized</var>] to
   <var>value</var>.<li>
    <p>If <var>deep</var> is true, then:</p>

    <ol><li>
      <p>If <var>serialized</var>.[[Type]] is "Map", then:</p>

      <ol><li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structureddeserialize:list-iterate data-x-internal=list-iterate>For each</a> <a id=structureddeserialize:record-2 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> { [[Key]], [[Value]] }
        <var>entry</var> of <var>serialized</var>.[[MapData]]:</p>

        <ol><li><p>Let <var>deserializedKey</var> be ?
         <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-3>StructuredDeserialize</a>(<var>entry</var>.[[Key]], <var>targetRealm</var>,
         <var>memory</var>).<li><p>Let <var>deserializedValue</var> be ?
         <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-4>StructuredDeserialize</a>(<var>entry</var>.[[Value]], <var>targetRealm</var>,
         <var>memory</var>).<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structureddeserialize:list-append data-x-internal=list-append>Append</a> { [[Key]]: <var>deserializedKey</var>,
         [[Value]]: <var>deserializedValue</var> } to <var>value</var>.[[MapData]].</ol>
       </ol>
     <li>
      <p>Otherwise, if <var>serialized</var>.[[Type]] is "Set", then:</p>

      <ol><li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structureddeserialize:list-iterate-2 data-x-internal=list-iterate>For each</a> <var>entry</var> of
        <var>serialized</var>.[[SetData]]:</p>

        <ol><li><p>Let <var>deserializedEntry</var> be ?
         <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-5>StructuredDeserialize</a>(<var>entry</var>, <var>targetRealm</var>,
         <var>memory</var>).<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structureddeserialize:list-append-2 data-x-internal=list-append>Append</a> <var>deserializedEntry</var> to
         <var>value</var>.[[SetData]].</ol>
       </ol>
     <li>
      <p>Otherwise, if <var>serialized</var>.[[Type]] is "Array" or "Object", then:</p>

      <ol><li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structureddeserialize:list-iterate-3 data-x-internal=list-iterate>For each</a> <a id=structureddeserialize:record-3 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> { [[Key]], [[Value]] }
        <var>entry</var> of <var>serialized</var>.[[Properties]]:</p>

        <ol><li><p>Let <var>deserializedValue</var> be ?
         <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-6>StructuredDeserialize</a>(<var>entry</var>.[[Value]], <var>targetRealm</var>,
         <var>memory</var>).<li><p>Let <var>result</var> be ! <a id=structureddeserialize:createdataproperty href=https://tc39.es/ecma262/#sec-createdataproperty data-x-internal=createdataproperty>CreateDataProperty</a>(<var>value</var>,
         <var>entry</var>.[[Key]], <var>deserializedValue</var>).<li><p><a id=structureddeserialize:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>result</var> is true.</ol>
       </ol>
     <li>
      <p>Otherwise:</p>

      <ol><li>
        <p>Perform the appropriate <a href=#deserialization-steps id=structureddeserialize:deserialization-steps>deserialization steps</a> for the interface identified
        by <var>serialized</var>.[[Type]], given <var>serialized</var>, <var>value</var>, and
        <var>targetRealm</var>.</p>

        <p>The <a href=#deserialization-steps id=structureddeserialize:deserialization-steps-2>deserialization steps</a> may need to perform a <dfn id=sub-deserialization data-export="">sub-deserialization</dfn>. This is an operation which takes as input a
        previously-serialized <a id=structureddeserialize:record-4 href=https://tc39.es/ecma262/#sec-list-and-record-specification-type data-x-internal=record>Record</a> <var>subSerialized</var>, and returns
        <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-7>StructuredDeserialize</a>(<var>subSerialized</var>, <var>targetRealm</var>,
        <var>memory</var>). (In other words, a <a href=#sub-deserialization id=structureddeserialize:sub-deserialization>sub-deserialization</a> is a specialization
        of <a href=#structureddeserialize id=structureddeserialize:structureddeserialize-8>StructuredDeserialize</a> to be consistent within this invocation.)</p>
       </ol>
    </ol>
   <li><p>Return <var>value</var>.</ol>

  <h4 id=structuredserializewithtransfer data-dfn-type=abstract-op data-lt=StructuredSerializeWithTransfer><span class=secno>2.7.7</span> <dfn>StructuredSerializeWithTransfer</dfn> ( <var>value</var>, <var>transferList</var>
  )<a href=#structuredserializewithtransfer class=self-link></a></h4>

  <ol><li>
    <p>Let <var>memory</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-map id=structuredserializewithtransfer:ordered-map data-x-internal=ordered-map>map</a>.</p>

    <p class=note>In addition to how it is used normally by
    <a href=#structuredserializeinternal id=structuredserializewithtransfer:structuredserializeinternal>StructuredSerializeInternal</a>, in this algorithm <var>memory</var> is also used to
    ensure that <a href=#structuredserializeinternal id=structuredserializewithtransfer:structuredserializeinternal-2>StructuredSerializeInternal</a> ignores items in <var>transferList</var>,
    and let us do our own handling instead.</p>
   <li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializewithtransfer:list-iterate data-x-internal=list-iterate>For each</a> <var>transferable</var> of
    <var>transferList</var>:</p>

    <ol><li><p>If <var>transferable</var> has neither an [[ArrayBufferData]] internal slot nor a
     <a href=#detached id=structuredserializewithtransfer:detached>[[Detached]]</a> internal slot, then throw a
     <a id=structuredserializewithtransfer:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializewithtransfer:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>transferable</var> has an [[ArrayBufferData]] internal slot and
     <a id=structuredserializewithtransfer:issharedarraybuffer href=https://tc39.es/ecma262/#sec-issharedarraybuffer data-x-internal=issharedarraybuffer>IsSharedArrayBuffer</a>(<var>transferable</var>) is true, then throw a
     <a id=structuredserializewithtransfer:datacloneerror-2 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializewithtransfer:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>memory</var>[<var>transferable</var>] <a href=https://infra.spec.whatwg.org/#map-exists id=structuredserializewithtransfer:map-exists data-x-internal=map-exists>exists</a>,
     then throw a <a id=structuredserializewithtransfer:datacloneerror-3 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializewithtransfer:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li>
      <p><a href=https://infra.spec.whatwg.org/#map-set id=structuredserializewithtransfer:map-set data-x-internal=map-set>Set</a> <var>memory</var>[<var>transferable</var>] to {
      [[Type]]: an uninitialized value }.</p>

      <p class=note><var>transferable</var> is not transferred yet as transferring has side
      effects and <a href=#structuredserializeinternal id=structuredserializewithtransfer:structuredserializeinternal-3>StructuredSerializeInternal</a> needs to be able to throw first.</p>
     </ol>
   <li><p>Let <var>serialized</var> be ? <a href=#structuredserializeinternal id=structuredserializewithtransfer:structuredserializeinternal-4>StructuredSerializeInternal</a>(<var>value</var>,
   false, <var>memory</var>).<li><p>Let <var>transferDataHolders</var> be a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structuredserializewithtransfer:js-list data-x-internal=js-list>List</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structuredserializewithtransfer:list-iterate-2 data-x-internal=list-iterate>For each</a> <var>transferable</var> of
    <var>transferList</var>:</p>

    <ol><li><p>If <var>transferable</var> has an [[ArrayBufferData]] internal slot and
     <a id=structuredserializewithtransfer:isdetachedbuffer href=https://tc39.es/ecma262/#sec-isdetachedbuffer data-x-internal=isdetachedbuffer>IsDetachedBuffer</a>(<var>transferable</var>) is true, then throw a
     <a id=structuredserializewithtransfer:datacloneerror-4 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializewithtransfer:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>transferable</var> has a <a href=#detached id=structuredserializewithtransfer:detached-2>[[Detached]]</a> internal slot and
     <var>transferable</var>.<a href=#detached id=structuredserializewithtransfer:detached-3>[[Detached]]</a> is true, then throw a
     <a id=structuredserializewithtransfer:datacloneerror-5 href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structuredserializewithtransfer:domexception-5><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>dataHolder</var> be <var>memory</var>[<var>transferable</var>].<li>
      <p>If <var>transferable</var> has an [[ArrayBufferData]] internal slot, then:</p>

      <ol><li>
        <p>If <var>transferable</var> has an [[ArrayBufferMaxByteLength]] internal slot, then:</p>

        <ol><li><p>Set <var>dataHolder</var>.[[Type]] to "ResizableArrayBuffer".<li><p>Set <var>dataHolder</var>.[[ArrayBufferData]] to
         <var>transferable</var>.[[ArrayBufferData]].<li><p>Set <var>dataHolder</var>.[[ArrayBufferByteLength]] to
         <var>transferable</var>.[[ArrayBufferByteLength]].<li><p>Set <var>dataHolder</var>.[[ArrayBufferMaxByteLength]] to
         <var>transferable</var>.[[ArrayBufferMaxByteLength]].</ol>
       <li>
        <p>Otherwise:</p>

        <ol><li><p>Set <var>dataHolder</var>.[[Type]] to "ArrayBuffer".<li><p>Set <var>dataHolder</var>.[[ArrayBufferData]] to
         <var>transferable</var>.[[ArrayBufferData]].<li><p>Set <var>dataHolder</var>.[[ArrayBufferByteLength]] to
         <var>transferable</var>.[[ArrayBufferByteLength]].</ol>
       <li>
        <p>Perform ? <a id=structuredserializewithtransfer:detacharraybuffer href=https://tc39.es/ecma262/#sec-detacharraybuffer data-x-internal=detacharraybuffer>DetachArrayBuffer</a>(<var>transferable</var>).</p>

        <p class=note>Specifications can use the [[ArrayBufferDetachKey]] internal slot to prevent
        <code id=structuredserializewithtransfer:idl-arraybuffer><a data-x-internal=idl-arraybuffer href=https://webidl.spec.whatwg.org/#idl-ArrayBuffer>ArrayBuffer</a></code>s from being detached. This is used in
        <cite>WebAssembly JavaScript Interface</cite>, for example. <a href=references.html#refsWASMJS>[WASMJS]</a></p>
       </ol>
     <li>
      <p>Otherwise:</p>

      <ol><li><p><a id=structuredserializewithtransfer:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>transferable</var> is a <a id=structuredserializewithtransfer:platform-object href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> that is
       a <a href=#transferable-objects id=structuredserializewithtransfer:transferable-objects>transferable object</a>.<li><p>Let <var>interfaceName</var> be the identifier of the <a id=structuredserializewithtransfer:primary-interface href=https://webidl.spec.whatwg.org/#dfn-primary-interface data-x-internal=primary-interface>primary interface</a>
       of <var>transferable</var>.<li><p>Set <var>dataHolder</var>.[[Type]] to <var>interfaceName</var>.<li><p>Perform the appropriate <a href=#transfer-steps id=structuredserializewithtransfer:transfer-steps>transfer steps</a> for the interface identified by
       <var>interfaceName</var>, given <var>transferable</var> and <var>dataHolder</var>.<li><p>Set <var>transferable</var>.<a href=#detached id=structuredserializewithtransfer:detached-4>[[Detached]]</a> to true.</ol>
     <li><p><a href=https://infra.spec.whatwg.org/#list-append id=structuredserializewithtransfer:list-append data-x-internal=list-append>Append</a> <var>dataHolder</var> to
     <var>transferDataHolders</var>.</ol>
   <li><p>Return { [[Serialized]]: <var>serialized</var>, [[TransferDataHolders]]:
   <var>transferDataHolders</var> }.</ol>

  <h4 id=structureddeserializewithtransfer data-dfn-type=abstract-op data-lt=StructuredDeserializeWithTransfer><span class=secno>2.7.8</span> <dfn>StructuredDeserializeWithTransfer</dfn> ( <var>serializeWithTransferResult</var>,
  <var>targetRealm</var> )<a href=#structureddeserializewithtransfer class=self-link></a></h4>

  <ol><li>
    <p>Let <var>memory</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-map id=structureddeserializewithtransfer:ordered-map data-x-internal=ordered-map>map</a>.</p>

    <p class=note>Analogous to <a href=#structuredserializewithtransfer id=structureddeserializewithtransfer:structuredserializewithtransfer>StructuredSerializeWithTransfer</a>, in addition to how it
    is used normally by <a href=#structureddeserialize id=structureddeserializewithtransfer:structureddeserialize>StructuredDeserialize</a>, in this algorithm <var>memory</var> is
    also used to ensure that <a href=#structureddeserialize id=structureddeserializewithtransfer:structureddeserialize-2>StructuredDeserialize</a> ignores items in
    <var>serializeWithTransferResult</var>.[[TransferDataHolders]], and let us do our own handling
    instead.</p>
   <li><p>Let <var>transferredValues</var> be a new empty <a href=https://tc39.es/ecma262/#sec-list-and-record-specification-type id=structureddeserializewithtransfer:js-list data-x-internal=js-list>List</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=structureddeserializewithtransfer:list-iterate data-x-internal=list-iterate>For each</a> <var>transferDataHolder</var> of
    <var>serializeWithTransferResult</var>.[[TransferDataHolders]]:</p>

    <ol><li><p>Let <var>value</var> be an uninitialized value.<li>
      <p>If <var>transferDataHolder</var>.[[Type]] is "ArrayBuffer", then set <var>value</var> to a
      new ArrayBuffer object in <var>targetRealm</var> whose [[ArrayBufferData]] internal slot value
      is <var>transferDataHolder</var>.[[ArrayBufferData]], and whose [[ArrayBufferByteLength]]
      internal slot value is <var>transferDataHolder</var>.[[ArrayBufferByteLength]].</p>

      <p class=note>In cases where the original memory occupied by [[ArrayBufferData]] is
      accessible during the deserialization, this step is unlikely to throw an exception, as no new
      memory needs to be allocated: the memory occupied by [[ArrayBufferData]] is instead just
      getting transferred into the new ArrayBuffer. This could be true, for example, when both the
      source and target realms are in the same process.</p>
     <li>
      <p>Otherwise, if <var>transferDataHolder</var>.[[Type]] is "ResizableArrayBuffer", then set
      <var>value</var> to a new ArrayBuffer object in <var>targetRealm</var> whose
      [[ArrayBufferData]] internal slot value is <var>transferDataHolder</var>.[[ArrayBufferData]],
      whose [[ArrayBufferByteLength]] internal slot value is
      <var>transferDataHolder</var>.[[ArrayBufferByteLength]], and whose
      [[ArrayBufferMaxByteLength]] internal slot value is
      <var>transferDataHolder</var>.[[ArrayBufferMaxByteLength]].</p>

      <p class=note>For the same reason as the previous step, this step is also unlikely to throw
      an exception.</p>
     <li>
      <p>Otherwise:</p>

      <ol><li><p>Let <var>interfaceName</var> be <var>transferDataHolder</var>.[[Type]].<li><p>If the interface identified by <var>interfaceName</var> is not exposed in
       <var>targetRealm</var>, then throw a <a id=structureddeserializewithtransfer:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a>
       <code id=structureddeserializewithtransfer:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>value</var> to a new instance of the interface identified by
       <var>interfaceName</var>, created in <var>targetRealm</var>.<li><p>Perform the appropriate <a href=#transfer-receiving-steps id=structureddeserializewithtransfer:transfer-receiving-steps>transfer-receiving steps</a> for the interface
       identified by <var>interfaceName</var> given <var>transferDataHolder</var> and
       <var>value</var>.</ol>
     <li><p><a href=https://infra.spec.whatwg.org/#map-set id=structureddeserializewithtransfer:map-set data-x-internal=map-set>Set</a> <var>memory</var>[<var>transferDataHolder</var>] to
     <var>value</var>.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=structureddeserializewithtransfer:list-append data-x-internal=list-append>Append</a> <var>value</var> to
     <var>transferredValues</var>.</ol>
   <li><p>Let <var>deserialized</var> be ?
   <a href=#structureddeserialize id=structureddeserializewithtransfer:structureddeserialize-3>StructuredDeserialize</a>(<var>serializeWithTransferResult</var>.[[Serialized]],
   <var>targetRealm</var>, <var>memory</var>).<li><p>Return { [[Deserialized]]: <var>deserialized</var>, [[TransferredValues]]:
   <var>transferredValues</var> }.</ol>


  <h4 id=performing-structured-clones-from-other-specifications><span class=secno>2.7.9</span> Performing serialization and
  transferring from other specifications<a href=#performing-structured-clones-from-other-specifications class=self-link></a></h4>

  <p>Other specifications may use the abstract operations defined here. The following provides
  some guidance on when each abstract operation is typically useful, with examples.</p>

  <dl><dt><a href=#structuredserializewithtransfer id=performing-structured-clones-from-other-specifications:structuredserializewithtransfer>StructuredSerializeWithTransfer</a><dt><a href=#structureddeserializewithtransfer id=performing-structured-clones-from-other-specifications:structureddeserializewithtransfer>StructuredDeserializeWithTransfer</a><dd>
    <p>Cloning a value to another <a id=performing-structured-clones-from-other-specifications:realm href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>, with a transfer list, but where the target
    realm is not known ahead of time. In this case the serialization step can be performed
    immediately, with the deserialization step delayed until the target realm becomes known.</p>

    <p class=example><code id=performing-structured-clones-from-other-specifications:dom-messageport-postmessage><a href=web-messaging.html#dom-messageport-postmessage>messagePort.postMessage()</a></code>
    uses this pair of abstract operations, as the destination realm is not known until the
    <code id=performing-structured-clones-from-other-specifications:messageport><a href=web-messaging.html#messageport>MessagePort</a></code> <a id=performing-structured-clones-from-other-specifications:has-been-shipped href=web-messaging.html#has-been-shipped>has been shipped</a>.</p>
   <dt><a href=#structuredserialize id=performing-structured-clones-from-other-specifications:structuredserialize>StructuredSerialize</a><dt><a href=#structuredserializeforstorage id=performing-structured-clones-from-other-specifications:structuredserializeforstorage>StructuredSerializeForStorage</a><dt><a href=#structureddeserialize id=performing-structured-clones-from-other-specifications:structureddeserialize>StructuredDeserialize</a><dd>
    <p>Creating a <a id=performing-structured-clones-from-other-specifications:realm-2 href=https://tc39.es/ecma262/#sec-code-realms data-x-internal=realm>realm</a>-independent snapshot of a given value which can be saved for an
    indefinite amount of time, and then reified back into a JavaScript value later, possibly
    multiple times.</p>

    <p><a href=#structuredserializeforstorage id=performing-structured-clones-from-other-specifications:structuredserializeforstorage-2>StructuredSerializeForStorage</a> can be used for situations where the serialization
    is anticipated to be stored in a persistent manner, instead of passed between realms. It throws
    when attempting to serialize <code id=performing-structured-clones-from-other-specifications:sharedarraybuffer><a data-x-internal=sharedarraybuffer href=https://tc39.es/ecma262/#sec-sharedarraybuffer-objects>SharedArrayBuffer</a></code> objects, since storing shared memory
    does not make sense. Similarly, it can throw or possibly have different behavior when given a
    <a id=performing-structured-clones-from-other-specifications:platform-object href=https://webidl.spec.whatwg.org/#dfn-platform-object data-x-internal=platform-object>platform object</a> with custom <a href=#serialization-steps id=performing-structured-clones-from-other-specifications:serialization-steps>serialization steps</a> when the
    <var>forStorage</var> argument is true.</p>

    <p class=example><code id=performing-structured-clones-from-other-specifications:dom-history-pushstate><a href=nav-history-apis.html#dom-history-pushstate>history.pushState()</a></code> and <code id=performing-structured-clones-from-other-specifications:dom-history-replacestate><a href=nav-history-apis.html#dom-history-replacestate>history.replaceState()</a></code> use
    <a href=#structuredserializeforstorage id=performing-structured-clones-from-other-specifications:structuredserializeforstorage-3>StructuredSerializeForStorage</a> on author-supplied state objects, storing them as
    <a id=performing-structured-clones-from-other-specifications:serialized-state href=browsing-the-web.html#serialized-state>serialized state</a> in the appropriate <a id=performing-structured-clones-from-other-specifications:session-history-entry href=browsing-the-web.html#session-history-entry>session history entry</a>. Then,
    <a href=#structureddeserialize id=performing-structured-clones-from-other-specifications:structureddeserialize-2>StructuredDeserialize</a> is used so that the <code id=performing-structured-clones-from-other-specifications:dom-history-state><a href=nav-history-apis.html#dom-history-state>history.state</a></code> property can return a clone of the
    originally-supplied state object.</p>

    <p class=example><code id=performing-structured-clones-from-other-specifications:dom-broadcastchannel-postmessage><a href=web-messaging.html#dom-broadcastchannel-postmessage>broadcastChannel.postMessage()</a></code> uses
    <a href=#structuredserialize id=performing-structured-clones-from-other-specifications:structuredserialize-2>StructuredSerialize</a> on its input, then uses <a href=#structureddeserialize id=performing-structured-clones-from-other-specifications:structureddeserialize-3>StructuredDeserialize</a>
    multiple times on the result to produce a fresh clone for each destination being broadcast
    to. Note that transferring does not make sense in multi-destination situations.</p>

    <p class=example>Any API for persisting JavaScript values to the filesystem would also use
    <a href=#structuredserializeforstorage id=performing-structured-clones-from-other-specifications:structuredserializeforstorage-4>StructuredSerializeForStorage</a> on its input and <a href=#structureddeserialize id=performing-structured-clones-from-other-specifications:structureddeserialize-4>StructuredDeserialize</a>
    on its output.</p>
   </dl>

  <p>In general, call sites may pass in Web IDL values instead of JavaScript values; this is to be
  understood to perform an implicit <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=performing-structured-clones-from-other-specifications:concept-idl-convert data-x-internal=concept-idl-convert>conversion</a> to the
  JavaScript value before invoking these algorithms.</p>

  <hr>

  <p>Call sites that are not invoked as a result of author code synchronously calling into a user
  agent method must take care to properly <a id=performing-structured-clones-from-other-specifications:prepare-to-run-script href=webappapis.html#prepare-to-run-script>prepare to run script</a> and <a id=performing-structured-clones-from-other-specifications:prepare-to-run-a-callback href=webappapis.html#prepare-to-run-a-callback>prepare to
  run a callback</a> before invoking <a href=#structuredserialize id=performing-structured-clones-from-other-specifications:structuredserialize-3>StructuredSerialize</a>,
  <a href=#structuredserializeforstorage id=performing-structured-clones-from-other-specifications:structuredserializeforstorage-5>StructuredSerializeForStorage</a>, or <a href=#structuredserializewithtransfer id=performing-structured-clones-from-other-specifications:structuredserializewithtransfer-2>StructuredSerializeWithTransfer</a>
  abstract operations, if they are being performed on arbitrary objects. This is necessary because
  the serialization process can invoke author-defined accessors as part of its final
  deep-serialization steps, and these accessors could call into operations that rely on the <a href=webappapis.html#concept-entry-everything id=performing-structured-clones-from-other-specifications:concept-entry-everything>entry</a> and <a href=webappapis.html#concept-incumbent-everything id=performing-structured-clones-from-other-specifications:concept-incumbent-everything>incumbent</a> concepts being properly set up.</p>

  <p class=example><code id=performing-structured-clones-from-other-specifications:dom-window-postmessage><a href=web-messaging.html#dom-window-postmessage>window.postMessage()</a></code> performs
  <a href=#structuredserializewithtransfer id=performing-structured-clones-from-other-specifications:structuredserializewithtransfer-3>StructuredSerializeWithTransfer</a> on its arguments, but is careful to do so
  immediately, inside the synchronous portion of its algorithm. Thus it is able to use the
  algorithms without needing to <a id=performing-structured-clones-from-other-specifications:prepare-to-run-script-2 href=webappapis.html#prepare-to-run-script>prepare to run script</a> and <a id=performing-structured-clones-from-other-specifications:prepare-to-run-a-callback-2 href=webappapis.html#prepare-to-run-a-callback>prepare to run a
  callback</a>.</p>

  <p class=example>In contrast, a hypothetical API that used <a href=#structuredserialize id=performing-structured-clones-from-other-specifications:structuredserialize-4>StructuredSerialize</a> to
  serialize some author-supplied object periodically, directly from a <a href=webappapis.html#concept-task id=performing-structured-clones-from-other-specifications:concept-task>task</a> on the <a id=performing-structured-clones-from-other-specifications:event-loop href=webappapis.html#event-loop>event loop</a>, would need to ensure it performs
  the appropriate preparations beforehand. As of this time, we know of no such APIs on the platform;
  usually it is simpler to perform the serialization ahead of time, as a synchronous consequence of
  author code.</p>

  

  <h4 id=structured-cloning><span class=secno>2.7.10</span> Structured cloning API<a href=#structured-cloning class=self-link></a></h4>

  <dl class=domintro><dt><code><var>result</var> = self.<a href=#dom-structuredclone id=dom-structuredclone-dev>structuredClone</a>(<var>value</var>[, { <a href=web-messaging.html#dom-structuredserializeoptions-transfer id=structured-cloning:dom-structuredserializeoptions-transfer>transfer</a> }])</code><dd>
    <p>Takes the input value and returns a deep copy by performing the structured clone algorithm.
    <a href=#transferable-objects id=structured-cloning:transferable-objects>Transferable objects</a> listed in the <code id=structured-cloning:dom-structuredserializeoptions-transfer-2><a href=web-messaging.html#dom-structuredserializeoptions-transfer>transfer</a></code> array are transferred, not
    just cloned, meaning that they are no longer usable in the input value.</p>

    <p>Throws a <a id=structured-cloning:datacloneerror href=https://webidl.spec.whatwg.org/#datacloneerror data-x-internal=datacloneerror>"<code>DataCloneError</code>"</a> <code id=structured-cloning:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if any part of
    the input value is not <a href=#serializable-objects id=structured-cloning:serializable-objects>serializable</a>.</p>
   </dl>

  

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/structuredClone title="The global structuredClone() method creates a deep clone of a given value using the structured clone algorithm.">structuredClone</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>94+</span></span><span class="safari yes"><span>Safari</span><span>15.4+</span></span><span class="chrome yes"><span>Chrome</span><span>98+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>98+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=WindowOrWorkerGlobalScope id=dom-structuredclone data-dfn-type=method><code>structuredClone(<var>value</var>,
  <var>options</var>)</code></dfn> method steps are:</p>

  <ol><li><p>Let <var>serialized</var> be ?
   <a href=#structuredserializewithtransfer id=structured-cloning:structuredserializewithtransfer>StructuredSerializeWithTransfer</a>(<var>value</var>, <var>options</var>["<code id=structured-cloning:dom-structuredserializeoptions-transfer-3><a href=web-messaging.html#dom-structuredserializeoptions-transfer>transfer</a></code>"]).<li><p>Let <var>deserializeRecord</var> be ?
   <a href=#structureddeserializewithtransfer id=structured-cloning:structureddeserializewithtransfer>StructuredDeserializeWithTransfer</a>(<var>serialized</var>, <a id=structured-cloning:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
   <a href=webappapis.html#concept-relevant-realm id=structured-cloning:concept-relevant-realm>relevant realm</a>).<li><p>Return <var>deserializeRecord</var>.[[Deserialized]].</ol>

  


  <nav><a href=common-dom-interfaces.html>← 2.6 Common DOM interfaces</a> — <a href=index.html>Table of Contents</a> — <a href=dom.html>3 Semantics, structure, and APIs of HTML documents →</a></nav>
